package com.kehutong.department.service;

import com.kehutong.common.DoveClient;
import com.kehutong.common.entity.Root;
import com.kehutong.common.entity.TreeUtil;
import com.kehutong.department.entity.Department;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;

import java.util.*;

/**
 * 部门服务
 *
 * @author liuzhen(liulei)
 * @createTime 2021年6月15日下午6:16:25
 */
@WebService("/basic/department/service/api")
public class DepartmentServiceApi {
	private static final Logger logger = LoggerFactory.getLogger(DepartmentServiceApi.class);
	@Inject
	private JdbcSession jdbcSession;
	@Inject
	private DoveClient doveClient;

	@ReqMapping("/list")
	public Object list(JSONObject json) {
		List<Department> list = jdbcSession.findArray(Department.class)
				.eq(json, "parent_id")
				.like(json, "parent_ids")
				.in(json, "id")
				.exe();

		list.forEach(dep ->{
			List<String> departmentName = new ArrayList<>();
			dep.getParent_ids().forEach(id->{
				if(!id.equals("1")){
					Department department = Pool.get(Department.class, id);
					departmentName.add(department.getName());
				}
			});
			departmentName.add(dep.getName());
			dep.setParent_names(String.join("-", departmentName));
		});

		return list;
	}
	@ReqMapping("/PageList")
	public Object PageList(JSONObject json) {
		logger.debug("{}=========", this.hashCode());
		Page<Department> page = jdbcSession.findPage(Department.class)
				.eq("deleted", false)
				.in(json, "id")
		      .page(json).exe();
		page.getList().forEach(dep ->{
			List<String> departmentName = new ArrayList<>();
			dep.getParent_ids().forEach(id->{
				if(!id.equals("1")){
					Department department = Pool.get(Department.class, id);
					departmentName.add(department.getName());
				}
			});
			departmentName.add(dep.getName());
			dep.setParent_names(String.join("-", departmentName));
		});
		return page;
	}


	@ReqMapping("/disposeDepartment")
	public Object disposeDepartment(JSONObject json) {
		List<String> departments = JSONObject.parseArray(json.getJSONArray("departments").toString(),String.class);

		List<Department> data = jdbcSession.findArray(Department.class)
				.eq("deleted", false)
				.exe();

		Map<String,Department> departmentMap = new HashMap<>();
		data.forEach(item->{
			String name = item.getName();
			String parent_id = item.getParent_id();
			String key = name + "-" + parent_id;
			departmentMap.put(key, item);
		});

		for (String item: departments) {
			List<String> items = Arrays.asList(item.split(","));
			for (String dep: items) {
				List<String> deps = Arrays.asList(dep.split("-"));
				String pid = Root.ROOT_ID;
				List<String> ids = new ArrayList<>();
				for (String name: deps) {
					//  查询到组织部门
					Department depItem = departmentMap.get(name + "-" + pid);
					if (Objects.isNull(depItem)) {
						// 未获取到部门信息 则新增部门
						ids.add(pid);
						depItem = Pool.newInstance(Department.class);
						depItem.setName(name);
						depItem.setParent_id(pid);
						depItem.setParent_ids(ids);
						jdbcSession.insert(depItem);

						//插入到list
						data.add(depItem);

						//插入到map
						departmentMap.put(name + "-" + pid, depItem);

						pid = depItem.getId();
					} else {
						ids = depItem.getParent_ids();
						ids.add(pid);
						pid = depItem.getId();
					}
				}
			}
		}

		return Result.success(data);
	}
	
	@ReqMapping("/get")
	public Object get(String id) {
		Department item = jdbcSession.findById(Department.class, id);
		if (Objects.nonNull(item) && item.isDeleted()) {
			return Result.success();
		}

		return item;
	}

	@Bean(newInstance = true, copy = true)
	@ReqMapping("/save")
	public Object save(Department item) throws Exception {
		// todo 需要添加验证
		if (Objects.isEmpty(item.getPid())) {
			item.setId(Root.ROOT_ID);
		}
		// 增加校验当前层级下不允许有相同的部门名称
		Department department = jdbcSession.findOne(Department.class)
				.eq("name", item.getName())
				.eq("parent_id", item.getParent_id())
				.eq("deleted", false)
				.exe();

		if(Objects.nonNull(department)){
			return Result.error(0, "当前部门下不允许有相同的部门名称");
		}
		jdbcSession.insert(item);
		return Result.success(item);
	}

	@Bean(copy = true)
	@ReqMapping("/update")
	public Object update(Department item) throws Exception {
		// todo 需要添加验证
		// 增加校验当前层级下不允许有相同的部门名称
		Department department = jdbcSession.findOne(Department.class)
				.eq("id", item.getId())
				.eq("deleted", false)
				.exe();

		if(!Objects.nonNull(department)){
			return Result.error(0, "未查询到数据");
		}
		jdbcSession.updateById(item);
		return Result.success(item);
	}

	@ReqMapping("/delete")
	public Object delete(Department item) throws Exception {
		JSONArray array = getEmployees(Arrays.asList(item.getId()));
		if(Objects.nonEmpty(array)){
			return Result.error(0, "需先删除该部门下的员工，再删除该部门！");
		}
		if (Objects.nonNull(item)) {
			item.setDeleted(true);
			jdbcSession.updateById(item);
		}
		return Result.success();
	}
	public JSONArray getEmployees(List<String> departments) throws Exception {

		JSONObject result = doveClient.post("/basic/employee/service/list", http->{
			JSONObject body = new JSONObject();
			body.put("department", departments);

			body.put("pageNo", 1);
			body.put("pageSize", 1000000);

			http.setBody(body.toString());
		});
		JSONArray data = result.getJSONObject("data").getJSONArray("list");
		if (Objects.isNull(data)) {
			return null;
		}
		return data;
	}
	@ReqMapping("/saveBatch")
	public Object saveBatch(JSONArray departments) {
		for (int i = 0; i < departments.size(); i ++) {
			JSONObject jsonObject = departments.getJSONObject(i);
			
			String id = jsonObject.getString("id");
			Department department = jdbcSession.findById(Department.class, id);
			if (Objects.isNull(department)) {
				department = Pool.newInstance(Department.class, id);
				department.setName(jsonObject.getString("name"));
				department.setSort(jsonObject.getIntValue("sort"));
				department.setParent_id(jsonObject.getString("parent_id"));
				department.setParent_ids(getParentIds(department.getParent_id()));
				jdbcSession.insert(department);
			} else {
				department.setName(jsonObject.getString("name"));
				department.setSort(jsonObject.getIntValue("sort"));
				department.setParent_id(jsonObject.getString("parent_id"));
				department.setParent_ids(getParentIds(department.getParent_id()));
				jdbcSession.updateById(department);
			}
		}
		
		return Result.success();
	}
	
	@ReqMapping("/listAll")
	public Object listAll(String departments) {
		if (Objects.isEmpty(departments)) {
			return jdbcSession.findArray(Department.class)
					.eq("deleted", false)
					.exe();
		}
		
		String[] str = departments.split(",");
		return jdbcSession.findArray(Department.class)
				.in("id", Arrays.asList(str))
				.eq("deleted", false)
				.exe();
	}
	
	@ReqMapping("/saveDepartment")
	public Object saveDepartment(JSONObject jsonObject) {
		JSONArray jsonArray = jsonObject.getJSONArray("data");
		for (int i = 0; i < jsonArray.size(); i ++) {
			JSONObject json = jsonArray.getJSONObject(i);
			Department department = Pool.get(Department.class, json.getString("id"));
			department.setMemCount(json.getIntValue("count"));
			department.setEmployeeIds(fromJsonArray(json.getJSONArray("leadIds")));
			department.setEmployeeNames(fromJsonArray(json.getJSONArray("leadNames")));
			jdbcSession.updateById(department);
		}



		//更新部门所有上级id
		List<Department> departmentList=jdbcSession.findArray(Department.class)
				.eq("deleted", false)
				.exe();
		Department isExitRoot = jdbcSession.findById(Department.class,Root.ROOT_ID);
		if(Objects.isNull(isExitRoot)){
			departmentList.add(Pool.newInstance(Department.class,Root.ROOT_ID));
		}
		Department root= TreeUtil.organizeAsTree(departmentList,false);
		setParent(root, root.getChildList());
		jdbcSession.updateById(departmentList);

		return Result.success();
	}

	private static void setParent(Department parent, List<Department> childList) {
		for (Department dpt : childList) {
			dpt.setParent_id(parent.getId());
			dpt.setParent_ids(toList(parent.getParent_ids(), parent.getId()));
			if(dpt.getChildList()!=null){
				setParent(dpt, dpt.getChildList());
			}
		}
	}

	private static  List<String> toList(List<String> pids, String pid) {
		if (Root.isRoot(pid)) {
			return Arrays.asList(pid);
		}

		List<String> list = new ArrayList<>(pids.size() +1);
		list.addAll(pids);
		list.add(pid);
		return list;
	}
	
	private List<String> getParentIds(String id) {
		List<String> list = new ArrayList<>(8);
		
		Department department = jdbcSession.findById(Department.class, id);
		while (Objects.nonNull(department)) {
			list.add(0, department.getId());
			department = jdbcSession.findById(Department.class, department.getParent_id());
		}
		
		return list;
	}
	
	private List<String> fromJsonArray(JSONArray aray) {
		List<String> strList = new ArrayList<>(aray.size());
		for (int i = 0; i < aray.size(); i ++) {
			strList.add(aray.getString(i));
		}
		return strList;
	}
}
